#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "MSTK.h"

#ifdef __cplusplus
extern "C" {
#endif

 /* 
    this function copy attribute information from submesh to mesh
    Assume mesh and submesh have the same attributes list

    attr_index: the attribute name
    part_no: partition number of submesh
 */

int MESH_CollectAttr(Mesh_ptr mesh, Mesh_ptr *submeshes, int num_mesh, const char *attr_name) {
  int i, j, num, ncomp, ival, global_index;
  double rval, *pval_arr;
  void *pval;
  MType mtype;

  MEntity_ptr local_ment, global_ment;
  MAttrib_ptr local_attrib, global_attrib;

  global_attrib = MESH_AttribByName(mesh,attr_name);

  /* get attribute properties */
  ncomp = MAttrib_Get_NumComps(global_attrib);
  mtype = MAttrib_Get_EntDim(global_attrib);

  global_index = 0;
  for(i = 0; i < num_mesh; i++) {
    local_attrib = MESH_AttribByName(submeshes[i],attr_name);
    /* attribute entity type */
    switch (mtype) {
    case MVERTEX:
      num = MESH_Num_Vertices(submeshes[i]);
      break;
    case MEDGE:
      num = MESH_Num_Edges(submeshes[i]);
      break;
    case MFACE:
      num = MESH_Num_Faces(submeshes[i]);
      break;
    case MREGION:
      num = MESH_Num_Regions(submeshes[i]);
      break;
    default:
      num = 0;
      MSTK_Report("MESH_CopyAttr()","Invalid entity type",FATAL);
    }
    
    
    /* collect data */
    for(j = 0; j < num; j++) {
      switch (mtype) { 
      case MVERTEX:
	local_ment = MESH_Vertex(submeshes[i],j);
	global_ment = MESH_Vertex(mesh,global_index);
	break;
      case MEDGE:
	local_ment = MESH_Edge(submeshes[i],j);
	global_ment = MESH_Edge(mesh,global_index);
	break;
      case MFACE:
	local_ment = MESH_Face(submeshes[i],j);
	global_ment = MESH_Face(mesh,global_index);
	break;
      case MREGION:
	local_ment = MESH_Region(submeshes[i],j);
	global_ment = MESH_Region(mesh,global_index);
	break;
      default:
	MSTK_Report("MESH_CollectAttr()","Invalid entity type",FATAL);
      }

      if(MEnt_MasterParID(local_ment) != i)
	continue;
      
      global_index++;
      MEnt_Get_AttVal(local_ment,local_attrib,&ival,&rval,&pval);
      if(ncomp > 1) {
	pval_arr = (double *)MSTK_malloc(ncomp*sizeof(double));
	pval_arr = (double *)pval;
      }	  
      MEnt_Set_AttVal(global_ment,global_attrib,ival,rval,(void*) pval_arr);
    }
  }
    
  return 1;
}
  
#ifdef __cplusplus
}
#endif

